﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using SunXNA.RainbowXNA.RenderObject;
using SunXNA.RainbowXNA.Material;
using SunXNA.RainbowXNA;

namespace SunXNA.RainbowXNA.Batch
{
    class CTerrainMaterialBatchRenderer : CMaterialBatchRenderer
    {
        private EffectParameter m_waterTexture;
        private EffectParameter m_sandTexture;
        private EffectParameter m_grassTexture;
        private EffectParameter m_mountainsTexture;

        public CTerrainMaterialBatchRenderer()
            : base()
        {
        }

        public override void Initialise(Effect effect)
        {
            m_effect = effect;

            m_viewParameter = m_effect.Parameters["xView"];
            m_worldParameter = m_effect.Parameters["xWorld"];
            m_projectionParameter = m_effect.Parameters["xProjection"];

            m_lightDirectionParameter = m_effect.Parameters["xLightDirection"];
            m_ambientParameter = m_effect.Parameters["xAmbient"];
            m_ambientParameter.SetValue(0.1f);

            m_waterTexture = m_effect.Parameters["xTexture0"];
            m_sandTexture = m_effect.Parameters["xTexture1"];
            m_grassTexture = m_effect.Parameters["xTexture2"];
            m_mountainsTexture = m_effect.Parameters["xTexture3"];

            CRainbowXNA.TextureObjectHandleType waterHandle = Singleton<CRainbowXNA>.Instance.LoadTexture("GameData/Images/Water");
            CRainbowXNA.TextureObjectHandleType sandHandle = Singleton<CRainbowXNA>.Instance.LoadTexture("GameData/Images/sand");
            CRainbowXNA.TextureObjectHandleType grassHandle = Singleton<CRainbowXNA>.Instance.LoadTexture("GameData/Images/grass");
            CRainbowXNA.TextureObjectHandleType rockHandle = Singleton<CRainbowXNA>.Instance.LoadTexture("GameData/Images/rock");

            m_waterTexture.SetValue(waterHandle.Texture);
            m_sandTexture.SetValue(sandHandle.Texture);
            m_grassTexture.SetValue(grassHandle.Texture);
            m_mountainsTexture.SetValue(rockHandle.Texture);
        }

        public override void Draw(ref Matrix m4View, ref Matrix m4Projection, ref GraphicsDevice device, ref Dictionary<UInt32, IBaseRenderObject> renderObjects, ref Dictionary<UInt32, Texture2D> textures, UInt32 textureHandle)
        {
            m_viewParameter.SetValue(m4View);
            m_projectionParameter.SetValue(m4Projection);

            m_lightDirectionParameter.SetValue(Vector3.Normalize(new Vector3(-1, -1, -1)));

            m_effect.Begin();
            {
                foreach (EffectPass pass in m_effect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    {

                        foreach (CRainbowXNA.CRenderInstance instance in m_batch)
                        {
                            Material.CBaseMaterial currentMaterial = instance.Material;
                            Matrix m4World = instance.World;
                            IBaseRenderObject renderObject = renderObjects[instance.ObjectHandle.UID];

                            m_worldParameter.SetValue(m4World);

                            m_effect.CommitChanges();

                            renderObject.Draw(device, m4World, m4View, m4Projection);
                        }

                    }
                    pass.End();
                }
            }
            m_effect.End();
        }
    }
}
